﻿using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Web;

namespace Ue.Utility
{
    public static class ImageHelper
    {
        /// <summary>
        /// 根据文件名，取得文件的解码器
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static ImageCodecInfo GetImageDecoder(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException("The fileName is null or empty.", "fileName");
            }

            string mimeType = string.Empty;
            switch (Path.GetExtension(fileName).ToLower())
            {
                case ".jpg":
                case ".jpeg":
                case ".jpe":
                case ".jfif":
                    mimeType = "image/jpeg";
                    break;
                case ".gif":
                    mimeType = "image/gif";
                    break;
                case ".png":
                    mimeType = "image/png";
                    break;
                case ".bmp":
                case ".dib":
                case ".rle":
                    mimeType = "image/bmp";
                    break;
                case ".tif":
                case ".tiff":
                    mimeType = "image/tiff";
                    break;
                case ".ico":
                    mimeType = "image/x-icon";
                    break;
                case ".wmf":
                    mimeType = "image/x-wmf";
                    break;
            }

            return ImageCodecInfo.GetImageEncoders().FirstOrDefault(item=>item.MimeType==mimeType);
        }

        /// <summary>
        /// 取得图片质量参数
        /// </summary>
        /// <param name="quality">图片质量系数，1-100</param>
        /// <returns></returns>
        public static EncoderParameters GetQualityEncoderParameters(int quality)
        {
            if (quality > 100 || quality < 0)
            {
                quality = 100;
            }

            var parameters = new EncoderParameters();
            parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);

            return parameters;
        
        }

        #region Compare Images

        /// <summary>
        /// 两张图片的对比结果
        /// </summary>
        public enum CompareResult
        {
            /// <summary>
            /// 相同
            /// </summary>
            CompareOk,
            /// <summary>
            /// 像素不匹配
            /// </summary>
            PixelMismatch,
            /// <summary>
            /// 大小不匹配
            /// </summary>
            SizeMismatch
        };


        /// <summary>
        /// 对比两张图片
        /// </summary>
        /// <param name="left">第一张图片</param>
        /// <param name="right">第二张图片</param>
        /// <returns>CompareResult</returns>
        public static CompareResult CompareTwoImages(Bitmap left, Bitmap right)
        {
            //大小不相同
            if (left.Size != right.Size)
            {
                return CompareResult.SizeMismatch;
            }

            //将图片转换为byte[]
            var imageConverter = new ImageConverter();
            var btImage1 = imageConverter.ConvertTo(left, typeof(byte[])) as byte[];
            var btImage2 = imageConverter.ConvertTo(right, typeof(byte[])) as byte[];

            //Compute a hash for each image
            var shaM = new SHA256Managed();
            byte[] hash1 = shaM.ComputeHash(btImage1);
            byte[] hash2 = shaM.ComputeHash(btImage2);

            //Compare the hash values
            for (int i = 0; i < hash1.Length && i < hash2.Length; i++)
            {
                if (hash1[i] != hash2[i])
                {
                    return CompareResult.PixelMismatch;
                }
            }

            return CompareResult.CompareOk;
        }

        #endregion

        #region Resize Image

        public enum ScaleMode
        {
            /// <summary>
            /// 指定高宽缩放（可能变形）
            /// </summary>
            HeightAndWidth,
            /// <summary>
            /// 指定宽，高按比例
            /// </summary>
            Width,
            /// <summary>
            /// 指定高，宽按比例
            /// </summary>
            Height,
            /// <summary>
            /// 指定高宽裁减（不变形）
            /// </summary>
            Cut
        };

        /// <summary>
        /// Resizes the image by a percentage
        /// </summary>
        /// <param name="imgPhoto">The img photo.</param>
        /// <param name="Percent">The percentage</param>
        /// <returns></returns>
        public static Image ResizeImageByPercent(Image imgPhoto, int Percent)
        {
            float nPercent = ((float)Percent / 100);

            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;

            int destX = 0;
            int destY = 0;
            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(destWidth, destHeight,
                                     PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                                    imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
                new Rectangle(destX, destY, destWidth, destHeight),
                new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
                GraphicsUnit.Pixel);

            grPhoto.Dispose();
            return bmPhoto;
        }


        /// <summary>
        /// 缩放、裁切图片
        /// </summary>
        /// <param name="originalImage"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static Image ResizeImageToAFixedSize(Image originalImage, int width, int height, ScaleMode mode)
        {
            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case ScaleMode.HeightAndWidth:
                    break;
                case ScaleMode.Width:
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case ScaleMode.Height:
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case ScaleMode.Cut:
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                default:
                    break;
            }
            //新建一个bmp图片
            Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

            //新建一个画布
            Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            //设置画布的描绘质量
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //清空画布并以透明背景色填充
            g.Clear(Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
                new Rectangle(x, y, ow, oh),
                GraphicsUnit.Pixel);

            g.Dispose();

            return bitmap;
        }

        #endregion
    }
}
